#ifndef __EXL_PS_TIMES_H__
#define __EXL_PS_TIMES_H__


#include <windows.h>
#include <exlbase.h>


namespace exl {
namespace ps {


template <BOOL (__stdcall *GetTimesFunction)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME)>
class SystemTimes
{
	// 1 s = 10^3 ms = 10^6 us = 10^9 ns
	__int64 kerneltime;		// 1 unidade = 100 ns = 100 * 10^-6 ms = 10^-4 ms
	__int64 usertime;
	HANDLE handle;

public:
	SystemTimes(HANDLE handle = NULL) : handle(handle)
	{
		if (handle && !load()) throw std::exception("Couldn't load process times");//TODO: exception!
	}

	bool load()
	{
		FILETIME CreationTime;
		FILETIME ExitTime;
		FILETIME KernelTime;
		FILETIME UserTime;
 		if (GetTimesFunction(handle, &CreationTime, &ExitTime, &KernelTime, &UserTime))
		{
			memcpy(&kerneltime, &KernelTime, sizeof(FILETIME));
			memcpy(&usertime, &UserTime, sizeof(FILETIME));
			return true;
		}
		else return false;
	}

	inline void setHandle(HANDLE h) { handle = h; }
	inline int getKernelMillis() { return int(kerneltime / 10000); }
	inline int getUserMillis() { return int(usertime / 10000); }
};


struct ProcessTimes : public SystemTimes <GetProcessTimes>
{
	ProcessTimes(HANDLE handle = NULL) : SystemTimes(handle) { }
};

struct ThreadTimes : public SystemTimes <GetThreadTimes>
{
	ThreadTimes(HANDLE handle = NULL) : SystemTimes(handle) { }
};


}
}

#endif
